<?php
// +----------------------------------------------------------------------
// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2014 http://www.thinkcmf.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: Tuolaji <479923197@qq.com>
// +----------------------------------------------------------------------

use think\Db;
use \app\portal\service\ApiService;
use \app\goods\service\GoodsApiService;
use \app\user\model\AssetModel;
use app\portal\model\PortalSensitiveModel;

/**
 * 查询文章列表,不做分页
 * 注:此方法查询时关联三个表term_relationships,posts,users;在指定查询字段(field),排序(order),指定查询条件(where)最好指定一下表名
 * @param string $tag <pre>查询标签,以字符串方式传入
 * 例："cid:1,2;field:posts.post_title,posts.post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"
 * ids:文章id,可以指定一个或多个文章id,以英文逗号分隔,如1或1,2,3
 * cid:文章所在分类,可指定一个或多个分类id,以英文逗号分隔,如1或1,2,3 默认值为全部
 * field:调用指定的字段
 *   如只调用posts表里的id和post_title字段可以是field:posts.id,posts.post_title; 默认全部,
 *   此方法查询时关联三个表term_relationships,posts,users;
 *   所以最好指定一下表名,以防字段冲突
 * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
 * order:排序方式,如按posts表里的post_date字段倒序排列：posts.post_date desc
 * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突</pre>
 * @param array $where 查询条件(只支持数组),格式和thinkphp的where方法一样,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突;
 * 
 */
function cmf_sql_posts($tag,$where=array()){
    return ApiService::postsNotPaged($tag,$where);
}

/**
 * 功能:查询文章列表,支持分页;<br>
 * 注:此方法查询时关联三个表term_relationships,posts,users;在指定查询字段(field),排序(order),指定查询条件(where)最好指定一下表名
 * @param string $tag <pre>查询标签,以字符串方式传入
 * 例："cid:1,2;field:posts.post_title,posts.post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"
 * ids:文章id,可以指定一个或多个文章id,以英文逗号分隔,如1或1,2,3
 * cid:文章所在分类,可指定一个或多个分类id,以英文逗号分隔,如1或1,2,3 默认值为全部
 * field:调用指定的字段
 *   如只调用posts表里的id和post_title字段可以是field:posts.id,posts.post_title; 默认全部,
 *   此方法查询时关联三个表term_relationships,posts,users;
 *   所以最好指定一下表名,以防字段冲突
 * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
 * order:排序方式,如按posts表里的post_date字段倒序排列：posts.post_date desc
 * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突</pre>
 * @param array $where 查询条件(只支持数组),格式和thinkphp的where方法一样,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突;
 * @param int $pagesize 每页条数,为0,false表示不分页
 * @param string $pagetpl 以字符串方式传入,例："{first}{prev}{liststart}{list}{listend}{next}{last}"
 * @return array 包括分页的文章列表<pre>
 * 格式:
 * array(
 *     "posts"=>array(),//文章列表,array
 * 	   "page"=>""//生成的分页html,不分页则没有此项
 *     "count"=>100 //符合条件的文章总数,不分页则没有此项
 * )</pre>
 */
function sp_posts($tag,$where=array(),$pagesize=0,$pagetpl=''){
    return ApiService::posts($tag,$where,$pagesize,$pagetpl);
}

/**
 * 功能：根据分类文章分类ID 获取该分类下所有文章(包含子分类中文章)
 * 注:此方法查询时关联三个表term_relationships,posts,users;在指定查询字段(field),排序(order),指定查询条件(where)最好指定一下表名
 * @author labulaka 2014-11-09 14:30:49
 * @param int $term_id 文章分类ID.
 * @param string $tag <pre>查询标签,以字符串方式传入
 * 例："cid:1,2;field:posts.post_title,posts.post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"
 * ids:文章id,可以指定一个或多个文章id,以英文逗号分隔,如1或1,2,3
 * cid:文章所在分类,可指定一个或多个分类id,以英文逗号分隔,如1或1,2,3 默认值为全部
 * field:调用指定的字段
 *   如只调用posts表里的id和post_title字段可以是field:posts.id,posts.post_title; 默认全部,
 *   此方法查询时关联三个表term_relationships,posts,users;
 *   所以最好指定一下表名,以防字段冲突
 * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
 * order:排序方式,如按posts表里的post_date字段倒序排列：posts.post_date desc
 * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突</pre>
 * @param array $where 查询条件(只支持数组),格式和thinkphp的where方法一样,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突;    
 */
function cmf_sql_posts_bycatid($term_id,$tag,$where=array()){
	return ApiService::postsByTermId($term_id,$tag,$where);
}

/**
 * 文章分页查询方法
 * @param string $tag  查询标签，以字符串方式传入,例："cid:1,2;field:post_title,post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"<br>
 * 	ids:调用指定id的一个或多个数据,如 1,2,3<br>
 * 	cid:数据所在分类,可调出一个或多个分类数据,如 1,2,3 默认值为全部,在当前分类为:'.$cid.'<br>
 * 	field:调用post指定字段,如(id,post_title...) 默认全部<br>
 * 	limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)<br>
 * 	order:排序方式，如：post_date desc<br>
 *	where:查询条件，字符串形式，和sql语句一样
 * @param int $pagesize 每页条数.
 * @return array 带分页数据的文章列表
 */
function cmf_sql_posts_paged($tag,$pagesize=20){
    $param          = cmf_param_lable($tag);
    $param['page']  = $pagesize;
    return ApiService::articles($param);
}

/**
 * 功能：根据关键字 搜索文章（包含子分类中文章）,已经分页,调用方式同cmf_sql_posts_paged<br>
 * 注:此方法查询时关联三个表term_relationships,posts,users;在指定查询字段(field),排序(order),指定查询条件(where)最好指定一下表名
 * @author WelkinVan 2014-12-04
 * @param string $keyword 关键字.
 
 * @param string $tag <pre>查询标签,以字符串方式传入
 * 例："cid:1,2;field:posts.post_title,posts.post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"
 * ids:文章id,可以指定一个或多个文章id,以英文逗号分隔,如1或1,2,3
 * cid:文章所在分类,可指定一个或多个分类id,以英文逗号分隔,如1或1,2,3 默认值为全部
 * field:调用指定的字段
 *   如只调用posts表里的id和post_title字段可以是field:posts.id,posts.post_title; 默认全部,
 *   此方法查询时关联三个表term_relationships,posts,users;
 *   所以最好指定一下表名,以防字段冲突
 * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
 * order:排序方式,如按posts表里的post_date字段倒序排列：posts.post_date desc
 * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突</pre>
 * @param array $where 查询条件(只支持数组),格式和thinkphp的where方法一样,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突;
 * @param int $pagesize 每页条数.
 */
function cmf_sql_posts_paged_bykeyword($keyword,$tag,$pagesize=20){
    return ApiService::postsPagedByKeyword($keyword,$tag,$pagesize);
}

/**
 * 根据分类文章分类ID 获取该分类下所有文章（包含子分类中文章）,已经分页
 * 注:此方法查询时关联三个表term_relationships,posts,users;在指定查询字段(field),排序(order),指定查询条件(where)最好指定一下表名
 * @author labulaka 2014-11-09 14:30:49
 * @param int $cid 文章分类ID.
 * @param string $tag <pre>查询标签,以字符串方式传入
 * 例："cid:1,2;field:posts.post_title,posts.post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"
 * ids:文章id,可以指定一个或多个文章id,以英文逗号分隔,如1或1,2,3
 * cid:文章所在分类,可指定一个或多个分类id,以英文逗号分隔,如1或1,2,3 默认值为全部
 * field:调用指定的字段
 *   如只调用posts表里的id和post_title字段可以是field:posts.id,posts.post_title; 默认全部,
 *   此方法查询时关联三个表term_relationships,posts,users;
 *   所以最好指定一下表名,以防字段冲突
 * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
 * order:排序方式,如按posts表里的post_date字段倒序排列：posts.post_date desc
 * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突</pre>
 * @param int $pagesize 每页条数.
 */
function cmf_sql_posts_paged_bycatid($term_id,$tag,$pagesize=20){
	return ApiService::postsPagedByTermId($term_id,$tag,$pagesize);
}

/**
 * 获取指定id的文章
 * @param int $post_id posts表下的id.
 * @param string $tag 查询标签，以字符串方式传入,例："field:post_title,post_content;"<br>
 *	field:调用post指定字段,如(id,post_title...) 默认全部<br>
 * @param array $where 查询条件(只支持数组),格式和thinkphp的where方法一样；
 * @return array 返回指定id的文章
 */
function sp_sql_post($post_id,$tag,$where=array()){
	return ApiService::post($post_id,$tag);
}

/**
 * 获取指定条件的页面列表
 * @param string $tag 查询标签，以字符串方式传入,例："ids:1,2;field:post_title,post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"<br>
 * 	ids:调用指定id的一个或多个数据,如 1,2,3<br>
 * 	field:调用post指定字段,如(id,post_title...) 默认全部<br>
 * 	limit:数据条数,默认值为10,可以指定从第几条开始,如0,8(表示共调用8条,从第1条开始)<br>
 * 	order:排序方式，如：post_date desc<br>
 *	where:查询条件，字符串形式，和sql语句一样
 * @param array $where 查询条件(只支持数组),格式和thinkphp的where方法一样；
 * @return array 返回符合条件的所有页面
 */
function sp_sql_pages($tag,$where=array()){
    return ApiService::pages($tag,$where);
}

/**
 * 获取指定id的页面
 * @param int $id 页面的id
 * @return array 返回符合条件的页面
 */
function sp_sql_page($id){
	return ApiService::page($id);
}


/**
 * 返回指定分类
 * @param int $term_id 分类id
 * @return array 返回符合条件的分类
 */
function sp_get_term($term_id){
    return ApiService::term($term_id);
}

/**
 * 返回指定分类下的子分类
 * @param int $term_id 分类id
 * @return array 返回指定分类下的子分类
 */
function sp_get_child_terms($term_id, $where=array(), $field=''){
	return ApiService::subCategories($term_id,$where,$field);
}

/**
 * 返回指定分类下的所有子分类
 * @param int $term_id 分类id
 * @return array 返回指定分类下的所有子分类
 */
function sp_get_all_child_terms($term_id){
    return ApiService::allSubCategories($term_id);
}

/**
 * 返回符合条件的所有分类
 * @param  array $param
 * @return array 返回符合条件的所有分类
 * 
 */
function sp_get_terms($param){
	return ApiService::categories($param);
}

/**
 * 获取Portal应用当前模板下的模板列表
 * @return array
 */
function sp_admin_get_tpl_file_list($dir){
	$template_path=C("SP_TMPL_PATH").C("SP_DEFAULT_THEME")."/Portal/";
    if($dir){
        $template_path.=$dir.'/';
    }
	$files=sp_scan_dir($template_path."*");
	$tpl_files=array();
	foreach ($files as $f){
		if($f!="." || $f!=".."){
			if(is_file($template_path.$f)){
				$suffix=C("TMPL_TEMPLATE_SUFFIX");
				$result=preg_match("/$suffix$/", $f);
				if($result){
					$tpl=str_replace($suffix, "", $f);
					$tpl_files[$tpl]=$tpl;
				}else if(preg_match("/\.php$/", $f)){
				    $tpl=str_replace($suffix, "", $f);
				    $tpl_files[$tpl]=$tpl;
				}
			}
		}
	}
	return $tpl_files;
}

/**
 *  获取面包屑数据
 * @param int $term_id 当前文章所在分类,或者当前分类的id
 * @param boolean $with_current 是否获取当前分类
 * @return array 面包屑数据
 */
function sp_get_breadcrumb($term_id,$with_current=false){
    return ApiService::breadcrumb($term_id,$with_current);
}

/**
 *  获取面包屑数据,并获取每个面包屑分类下的子分类
 * @param int $term_id 当前文章所在分类,或者当前分类的id
 * @param boolean $with_current 是否获取当前分类
 * @return array 面包屑数据
 */
function sp_get_breadcrumb_child($term_id,$with_current=false){
    $breadcrumb = ApiService::breadcrumb($term_id,$with_current);
    foreach ($breadcrumb as $k => $v) {
        $where = [
            'id'      => ['neq', $v['id']],
        ];
        $breadcrumb[$k]['child'] = sp_get_child_terms($v['parent_id'], $where);
    }
    return $breadcrumb;
}


/**
 * 查询文章列表,不做分页
 * 注:此方法查询时关联三个表term_relationships,posts,users;在指定查询字段(field),排序(order),指定查询条件(where)最好指定一下表名
 * @param string $tag <pre>查询标签,以字符串方式传入
 * 例："cid:1,2;field:posts.post_title,posts.post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"
 * ids:文章id,可以指定一个或多个文章id,以英文逗号分隔,如1或1,2,3
 * cid:文章所在分类,可指定一个或多个分类id,以英文逗号分隔,如1或1,2,3 默认值为全部
 * field:调用指定的字段
 *   如只调用posts表里的id和post_title字段可以是field:posts.id,posts.post_title; 默认全部,
 *   此方法查询时关联三个表term_relationships,posts,users;
 *   所以最好指定一下表名,以防字段冲突
 * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
 * order:排序方式,如按posts表里的post_date字段倒序排列：posts.post_date desc
 * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突</pre>
 * @param array $where 查询条件(只支持数组),格式和thinkphp的where方法一样,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突;
 * 
 */
function branch_cmf_sql_posts($tag,$where=array()){
    return ApiService::branchPostsNotPaged($tag,$where);
}





/**
 * 返回指定分类下的子分类
 * @param int $term_id 分类id
 * @return array 返回指定分类下的子分类
 */
function cmf_get_goods_child_terms($term_id, $tag='', $where=array()){
    return GoodsApiService::subCategories($term_id, $tag, $where);
}


/**
 *  获取面包屑数据
 * @param int $term_id 当前产品所在分类,或者当前分类的id
 * @param boolean $with_current 是否获取当前分类
 * @return array 面包屑数据
 */
function cmf_get_goods_breadcrumb($term_id,$with_current=false,$tag='',$where=[]){
    return GoodsApiService::breadcrumb($term_id, $with_current, $tag, $where);
}

/**
 *  获取面包屑数据,并获取每个面包屑分类下的子分类
 * @param int $term_id 当前文章所在分类,或者当前分类的id
 * @param boolean $with_current 是否获取当前分类
 * @return array 面包屑数据
 */
function cmf_get_goods_breadcrumb_child($term_id,$with_current=false){
    $breadcrumb = GoodsApiService::breadcrumb($term_id,$with_current);

    foreach ($breadcrumb as $k => $v) {
        $breadcrumb[$k]['child'] = cmf_get_goods_child_terms($v['parent_id'], '', array('id'=>array('neq',$v['id'])) );
    }
    return $breadcrumb;
}

/**
 * 功能：根据分类文章分类ID 获取该分类下所有文章(包含子分类中文章)
 * 注:此方法查询时关联三个表term_relationships,posts,users;在指定查询字段(field),排序(order),指定查询条件(where)最好指定一下表名
 * @author labulaka 2014-11-09 14:30:49
 * @param int $term_id 文章分类ID.
 * @param string $tag <pre>查询标签,以字符串方式传入
 * 例："cid:1,2;field:posts.post_title,posts.post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"
 * ids:文章id,可以指定一个或多个文章id,以英文逗号分隔,如1或1,2,3
 * cid:文章所在分类,可指定一个或多个分类id,以英文逗号分隔,如1或1,2,3 默认值为全部
 * field:调用指定的字段
 *   如只调用posts表里的id和post_title字段可以是field:posts.id,posts.post_title; 默认全部,
 *   此方法查询时关联三个表term_relationships,posts,users;
 *   所以最好指定一下表名,以防字段冲突
 * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
 * order:排序方式,如按posts表里的post_date字段倒序排列：posts.post_date desc
 * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突</pre>
 * @param array $where 查询条件(只支持数组),格式和thinkphp的where方法一样,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突;    
 */
function cmf_sql_goods_bycatid($term_id,$tag='',$where=array()){
    return GoodsApiService::goodsByTermId($term_id,$tag,$where);
}

/**
 * 查询产品列表,不做分页
 * 注:此方法查询时关联三个表term_relationships,posts,users;在指定查询字段(field),排序(order),指定查询条件(where)最好指定一下表名
 * @param string $tag <pre>查询标签,以字符串方式传入
 * 例："cid:1,2;field:posts.post_title,posts.post_content;limit:0,8;order:post_date desc,listorder desc;where:id>0;"
 * ids:产品id,可以指定一个或多个产品id,以英文逗号分隔,如1或1,2,3
 * cid:产品所在分类,可指定一个或多个分类id,以英文逗号分隔,如1或1,2,3 默认值为全部
 * field:调用指定的字段
 *   如只调用posts表里的id和post_title字段可以是field:posts.id,posts.post_title; 默认全部,
 *   此方法查询时关联三个表term_relationships,posts,users;
 *   所以最好指定一下表名,以防字段冲突
 * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
 * order:排序方式,如按posts表里的post_date字段倒序排列：posts.post_date desc
 * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突</pre>
 * @param array $where 查询条件(只支持数组),格式和thinkphp的where方法一样,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突;
 * 
 */
function cmf_sql_goods($tag,$where=array()){
    return GoodsApiService::goodsNotPaged($tag,$where);
}

/**
 * 创建像这样的查询: "IN('a','b')";
 *
 * @access   public
 * @param    mix      $item_list      列表数组或字符串
 * @param    string   $field_name     字段名称
 *
 * @return   void
 */
function db_create_in($item_list, $field_name = '')
{
    if (empty($item_list))
    {
        return $field_name . " IN ('') ";
    }
    else
    {
        if (!is_array($item_list))
        {
            $item_list = explode(',', $item_list);
        }
        $item_list = array_unique($item_list);
        $item_list_tmp = '';
        foreach ($item_list AS $item)
        {
            if ($item !== '')
            {
                $item_list_tmp .= $item_list_tmp ? ",'$item'" : "'$item'";
            }
        }
        if (empty($item_list_tmp))
        {
            return $field_name . " IN ('') ";
        }
        else
        {
            return $field_name . ' IN (' . $item_list_tmp . ') ';
        }
    }
}


//以下为新增

/**
  +----------------------------------------------------------
 * 原样输出print_r的内容
  +----------------------------------------------------------
 * @param string    $content   待print_r的内容
  +----------------------------------------------------------
 */
function pre($content,$on=false){
    header("Content-type: text/html; charset=utf-8"); 
    echo '<pre>';
    print_r($content);
    echo '</pre>';
    if($on) die;
}

function del_file($path){
    $adminId   = cmf_get_current_admin_id();
    $userId    = cmf_get_current_user_id();
    $userId    = empty($adminId) ? $userId : $adminId;


    $path = str_replace('/upload/', '', $path);
    // pre($path,1);
    $SaveFilePath  = config('upload_path').$path;
    @$file_md5     = md5_file($SaveFilePath);
    @$file_sha1    = sha1_file($SaveFilePath);
    @$file_key     = $file_md5 . md5($file_sha1);
    // $file_key     = md5($SaveFilePath).md5_file($SaveFilePath);

    $assetModel = new AssetModel();

    if( !empty($file_key) ){
        $res = $assetModel->where("file_key", $file_key)->delete();
    }

    // if( $res ){
        @unlink($SaveFilePath);     //删除文件
    // }
}

/**
 * 字符串截取，支持中文和其他编码
 * @static
 * @access public
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) {
    if(function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif(function_exists('iconv_substr')) {
        $slice = iconv_substr($str,$start,$length,$charset);
        if(false === $slice) {
            $slice = '';
        }
    }else{
        $re['utf-8']   = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("",array_slice($match[0], $start, $length));
    }
    if( $suffix ){
        if( strlen($str)>$length ){
            if($slice != $str)$slice .= '...';
        }
    }
    return $slice;
}

/**
 * 根据过滤条件获得排序的标记
 *
 * @access  public
 * @param   array   $filter
 * @return  array
 */
function sort_flag($filter)
{
    $flag['tag']    = 'sort_' . preg_replace('/^.*\./', '', $filter['sort_by']);
    // $flag['tag']    = 'sort_' . $filter['sort_by'];
    // $flag['img']    = '<img src="/public/images/' . ($filter['sort_order'] == "DESC" ? 'sort_desc.gif' : 'sort_asc.gif') . '"/>';
    $flag['img']    = '&nbsp;<i class="listorder f-s-12 fa fa-caret-' . ($filter['list_order'] == "DESC" ? 'down' : 'up') . '"></i>';

    return $flag;
}

/**
 * 获取分类缩略图尺寸
 * @access public
 * @param int $cat_id 分类id
 * @param string $table 要查询的数据表名
 * @return string
 */
function get_thumb_size($cat_id, $table='PortalCategory'){
    $thumb_size = '';
    if( empty($cat_id) ) return $thumb_size;
    
    $data = Db::name($table)->field('parent_id,thumb_size')->find($cat_id);
    if( !empty($data) ){
        if( empty($data['thumb_size']) ){
            $thumb_size = get_thumb_size($data['parent_id'], $table);
        }else {
            $thumb_size = $data['thumb_size'];
        }
    }

    return $thumb_size;
}




/**
 * 获得商品类型的列表
 *
 * @access  public
 * @param   integer     $selected   选定的类型编号
 * @return  string
 */
function goods_type_list($selected='')
{
    $where = [
        'enabled' => 1,
        'site_id' => get_site_id(),
    ];
    $type_list = Db::name('goods_type')->field('cat_id, cat_name')->where($where)->select();

    foreach ($type_list as $k => $v) {
        $data[$v['cat_id']] = $v['cat_name'];
    }

    return html_options($data, $selected);
}

/**
 * 创建select框下的option
 *
 * @access  public
 * @param   array     $options   一维关联数组
 * @return  string    $selected  要选中的键(key)
 * @return  array     $disableds  要禁止选择的键(key)
 */
function html_options($options, $selected='', $disableds=[])
{
    // $selected = $arr['selected'];
    // if ($arr['options'])
    // {
    //     $options = (array)$arr['options'];
    // }
    // elseif ($arr['output'])
    // {
    //     if ($arr['values'])
    //     {
    //         foreach ($arr['output'] AS $key => $val)
    //         {
    //             $options["{$arr[values][$key]}"] = $val;
    //         }
    //     }
    //     else
    //     {
    //         $options = array_values((array)$arr['output']);
    //     }
    // }
    if ($options)
    {
        foreach ($options AS $key => $val)
        {
            $disabled = $selectedStr = '';

            // 是否禁用
            if( in_array($key, $disableds) ){
                $disabled = 'disabled style="background: #ccc;"';
            }

            // 是否选中
            if( $key == $selected ){
                $selectedStr = 'selected';
            }

            $out .=  "<option value=\"$key\" $selectedStr $disabled >$val</option>";
        }
    }

    return $out;
}

/**
 * 根据幻灯片标识获取所有幻灯片
 * @param string $slide 幻灯片标识
 * @return array;
 */
function cmf_getslide($slide, $limit=5){
    return app\admin\service\ApiService::slides($slide,$limit);
}

/**
 * 获取所有审核流程
 * @param string $slide 幻灯片标识
 * @return array;
 */
function get_audit_flow($selected=''){
    $audit_list = Db::name('audit_flow')
               -> field('audit_id,name')
               -> order('audit_id asc')
               -> select();
    foreach ($audit_list as $k => $v) {
        $options[$v['audit_id']] = $v['name'];
    }

    $data = html_options($options, $selected);

    return $data;
}

function get_module($selected=''){
    $module_list = Db::name('module')->select();
    foreach ($module_list as $k => $v) {
        $options[$v['name']] = $v['alias'];
    }

    $data = html_options($options, $selected);

    return $data;
}

/**
 * 查询部分分类中是否存在需要使用审核流程的分类
 * @param  array     $categories 分类id
 * @param  string    $table_name 分类表名
 * @return string;
 */
function get_audit_id($categories, $table_name='portal_category'){
    foreach ($categories as $k => $v) {
        $audit_id = Db::name($table_name)->where('id',$v)->value('audit_id');
        if( !empty($audit_id) ){
            return $audit_id;
        }
    }
}


/**
 * 分页函数
 * @param $current  当前页
 * @param $count    记录总数
 * @param $limit    每页显示多少条
 * @param $size     中间显示多少条
 * @param $class    样式
*/
function page($current,$count,$limit,$size,$class='pagination',$urlMode=0){
    $str='';
    if($count>$limit){
        $pages = ceil($count/$limit);//算出总页数
        $url = 'javascript:;';//获取当前页面的URL地址（包含参数）
        if( $urlMode == 1 ){
            $url = get_url();//获取当前页面的URL地址（包含参数）
        }

        $str.='<ul class="'.$class.'">';
        //开始
        if($current==1){
            // $str.='<li class="disabled"><span>首&nbsp;&nbsp;页</span></li>';
            $str.='<li class="disabled"><span>  « </span></li>';
        }else{
            // $str.='<li><a href="'.$url.'" data-page="1">首&nbsp;&nbsp;页 </a></li>';
            $str.='<li><a href="'.$url.'" data-page='.($current-1).'>  « </a></li>';
        }
        //中间
        //判断得出star与end
        
         if($current<=floor($size/2)){ //情况1
            $star=1;
            $end=$pages >$size ? $size : $pages; //看看他两谁小，取谁的
         }else if($current>=$pages - floor($size/2)){ // 情况2
                 
            $star=$pages-$size+1<=0?1:$pages-$size+1; //避免出现负数
        
            $end=$pages;
         }else{ //情况3
         
            $d=floor($size/2);
            $star=$current-$d;
            $end=$current+$d;
         }
    
        for($i=$star;$i<=$end;$i++){
            if($i==$current){
                $str.='<li class="active"><span>'.$i.'</span></li>';    
            }else{
                $str.='<li><a href="'.$url.'" data-page='.$i.'>'.$i.'</a></li>';
            }
        }
        //最后
        if($pages==$current){
            $str .='<li class="disabled"><span >  » </span></li>';
            // $str.='<li class="disabled"><span >尾&nbsp;&nbsp;页  </span></li>';
        }else{
            $str.='<li><a href="'.$url.'" data-page='.($current+1).'>» </a></li>';
            // $str.='<li><a href="'.$url.'" data=page='.$pages.'>尾&nbsp;&nbsp;页 </a></li>';
        }
        $str.='</ul>';
    }
    
    return $str;
}

/**
 * 获取某个表的列表项
 * @param string    $table_name     表名
 * @param int       $status         状态
 * @param array
*/
function get_list_item_column($table_name, $status=1){
   $where = [
       'table_name' => $table_name,
       'status'     => $status,
   ];
   
   $data = db('listItem')
        -> where($where)
        -> column('field'); 

   return $data;
}

/**
 * 获取栏目深度
 * @param $id
 * @param array $array
 * @param int $i
 * @return int
 */
function getLevel($id, $array = [], $i = 0)
{   
    if ($array[$id]['parent_id'] == 0 || empty($array[$array[$id]['parent_id']]) || $array[$id]['parent_id'] == $id) {
        return $i;
    } else {
   
        $i++;
      
        return getLevel($array[$id]['parent_id'], $array, $i);
    }
}

//导出下载Excel
function exportExcel($expTitle='Excel',$expCellName,$expTableData){
    // $xlsTitle = iconv('utf-8', 'gb2312', $expTitle);//文件名称
    // $fileName = "文章点击量统计_".date('YmdHis');//or $xlsTitle 文件名称可根据自己情况设定
    $cellNum = count($expCellName);
    $dataNum = count($expTableData);
    vendor("PHPExcel.PHPExcel");
   
    $objPHPExcel = new \PHPExcel();
    $cellName = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ');
    
    $objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10);
    // $objPHPExcel->getActiveSheet(0)->mergeCells('A1:'.$cellName[$cellNum-1].'1');//合并单元格
    // $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', $expTitle.'  Export time:'.date('Y-m-d H:i:s'));
    for($i=0;$i<$cellNum;$i++){
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue($cellName[$i].'1', $expCellName[$i][1]);
    }
    // Miscellaneous glyphs, UTF-8
    for($i=0;$i<$dataNum;$i++){
        for($j=0;$j<$cellNum;$j++){
            $objPHPExcel->getActiveSheet(0)->setCellValue($cellName[$j].($i+2), $expTableData[$i][$expCellName[$j][0]]);
        }
    }

   //  $objPHPExcel->getActiveSheet(0)->mergeCells('A1:'.$cellName[$cellNum-1].'1');//合并单元格
   // // $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', $expTitle.'  Export time:'.date('Y-m-d H:i:s'));  
   //  for($i=0;$i<$cellNum;$i++){
   //      $objPHPExcel->setActiveSheetIndex(0)->setCellValue($cellName[$i].'2', $expCellName[$i][1]); 
   //  } 
   //    // Miscellaneous glyphs, UTF-8   
   //  for($i=0;$i<$dataNum;$i++){
   //    for($j=0;$j<$cellNum;$j++){
   //      $objPHPExcel->getActiveSheet(0)->setCellValue($cellName[$j].($i+3), $expTableData[$i][$expCellName[$j][0]]);
   //    }             
   //  }  
    
    header('pragma:public');
    header('Content-type:application/vnd.ms-excel');
    // header('Content-type:application/vnd.ms-excel;charset=utf-8;name="'.$xlsTitle.'.xls"');
    header("Content-Disposition:attachment;filename=$expTitle.xls");//attachment新窗口打印inline本窗口打印
    $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');//Excel5为xls格式，excel2007为xlsx格式
    $objWriter->save('php://output'); 
    exit;   
}

/**
 * /
 * @param  int     $cat_id      [分类id]
 * @param  boolean $includeself [是否包括自身cat_id]
 * @param  string  $model       [数据库表名]
 * @return array                [当前分类的父]
 */
function get_cat_parent_path($cat_id, $includeself=true, $model = 'portal_category'){
    $path    = Db::name($model)
            -> where(['id' => $cat_id])
            -> value('path');

    $parents = explode('-', $path);

    //去除顶级分类0
    array_shift($parents);

    //是否去除自身分类id
    if(!$includeself) array_shift($parents);

    return $parents;
}

/*function cat_auth_check($cat_id, $power='add', $column_type=1){
    if( session('ROLE_ID') == 1 )   return 1;
    
    $where = [
        'column_type' => $column_type,
        'role_id'     => session('ROLE_ID'),
    ];

    if( is_array($cat_id) ){
        $where['cat_id'] = ['in', $cat_id];
    }else{
        $where['cat_id'] = $cat_id;
    }

    $count = Db::name('auth_access')
          -> where($where)
          -> where("find_in_set('".$power."', power)")
          -> count();

    return ($count>0) ? 1 : 0;

    // $model = ($column_type==1) ? 'portal_category' : 'goods_category';

    // $cat_ids = [];
    // if( is_array($cat_id) ){
    //     foreach ($cat_id as $k => $v) {
    //         $path    = Db::name($model)->where('id', $v)->value('path');
    //         $ids     = explode('-',$path);
    //         $cat_ids = array_merge($cat_ids, $ids);
    //     }
    //     $cat_ids = array_unique($cat_ids);
    // }else{
    //     $path = Db::name($model)->where('id', $cat_id)->value('path');
    //     $cat_ids = explode('-',$path);
    // }

    // $where = [
    //     'column_type' => $column_type,
    //     'cat_id'      => ['in', $cat_ids],
    // ];

    // $count = Db::name('auth_access')
    //       -> where($where)
    //       -> where("find_in_set('".$power."', power)")
    //       -> count();

    // return ($count>0) ? 1 : 0;
}*/


/**
 * 检查敏感词
 * @param   $key   string   要检查的字段
 * @param   $data  string   要检查的数据
 * @return  html   string   提示语
 * 
 */
function check_sensitive_words($key, $data) {
    /**
    * 获取敏感词库
    */
    $sensitive = db('portal_sensitive')
              -> field('name, displace')
              -> where('status',1)
              -> select();
    
    if( !empty($sensitive) ){
        $html   = '';
        $count  = count($sensitive);
        
        for($i = 0; $i< $count; $i++){
            if(strpos($data, $sensitive[$i]['name']) !== false){
                $html .= '<p>“'.lang($key).'”含有敏感词:“<span class="highlight">'.$sensitive[$i]['name'].'</span>”'
                .'将被替换为:“<span class="highlight">'.$sensitive[$i]['displace'].'</span>”</p>';
            }
        }
    }

    return $html;
}

/**
 * @param  string $tableName    栏目分类表名
 * @param  string $action       操作名
 * @return array  $idList       可操作的栏目分类ID
 */
function get_cat_priv($action='init', $tableName='portal_category'){
    $roleId = session('ROLE_ID');   //当前角色ID
    $siteId = session('SITE_ID');   //当前站点ID

    $idList = [];
    if( $roleId != 1 ){
        $where = [
            'role_id'    => $roleId,
            'site_id'    => $siteId,
            'table_name' => $tableName,
            'action'     => $action,
        ];
        $idList = Db::name('category_priv')->where($where)->column('cat_id');    
    }

    return $idList;
}

/**
 * 检查角色是否拥有某分类的某个操作权限
 * @param  string/array $catId          要检查的分类id
 * @param  string       $action         操作
 * @param  string       $tableName      栏目分类表名
 * @return boolean            
 */
function check_cat_priv($catId, $action = 'init', $tableName = 'portal_category'){
    $roleId = session('ROLE_ID');   //当前角色ID
    $siteId = session('SITE_ID');   //当前站点ID

    if( $roleId == 1 )   return 1;
    
    $where = [
        'role_id'    => $roleId,
        'site_id'    => $siteId,
        'table_name' => $tableName,
        'action'     => $action,
    ];

    if( is_array($catId) ){
        $where['cat_id'] = ['in', $catId];
    }else{
        $where['cat_id'] = $catId;
    }

    $count = Db::name('category_priv')
          -> where($where)
          -> count();

    return ($count>0) ? 1 : 0;
}

/**
 * @param  int $siteId    站点ID
 * @return boolean
 */
function check_site_exist($siteId){
    if( db('site')->where('site_id', $siteId)->count() ){
        return true;
    }

    return false;
}

/**
 * 获取当前的站点ID
 * @return int
 */
function get_site_id($type=''){
    if( $type === 'cookie'){
        $siteId = cookie('SITE_ID');
    }else{
        $siteId = session('SITE_ID');
    }

    return $siteId;
}


/**
 * 格式化字节大小
 * @param  number $size      字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function format_bytes($size, $delimiter = '') {
    $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
    return round($size, 2) . $delimiter . $units[$i];
}



/**
 * 敏感词过滤
 * @param $data  文章数据
 * 
 */
function cmf_replaceSensitive($data) {
    /**
    * 获取敏感词库并进行敏感词替换
    */
    $portalSensitiveModel = new portalSensitiveModel();

    $sensitive = $portalSensitiveModel
              -> field('name, displace')
              -> where('status',1)
              -> select();
  
    if( !empty($sensitive) ){
        $count = count($sensitive);
      
        for($i = 0; $i< $count; $i++){
            if( strpos($data, $sensitive[$i]['name']) !== false){
                $data = str_replace($sensitive[$i]['name'],$sensitive[$i]['displace'],$data);
            }
        }
        
    }

    return $data;
}

/**
 * 敏感词过滤
 * @param $data  文章数据
 * 
 */
function cmf_replaceSensitive2($data) {
    /*
     * 获取敏感词库并进行敏感词替换
     */
    $portalSensitiveModel = new portalSensitiveModel();

    $sensitive = $portalSensitiveModel
              -> field('name, displace')
              -> where('status',1)
              -> select();
    
    if(isset($sensitive)){

        $count = count($sensitive);
        
        $result = array();
        for($i = 0; $i< $count; $i++){
            if(strpos($data[1],$sensitive[$i]['name']) !== false){
                $result[$i]['name'] = $sensitive[$i]['name'];
                $result[$i]['displace'] = $sensitive[$i]['displace'];
            }
        }
        
        if($result){
            $html = '';
            /*$result = implode(',', $result);*/
            foreach ($result as $key => $value) {
                $html .= '<p>“'.lang($data[0]).'”含有敏感词:<span>“'.$value['name']."”</span>将被替换为:<span>“".$value['displace']."”</span></p>";
            }
            
        }
    }
    //print_r($result);exit;

    return $html;
}

/**
 * 记录管理员的操作内容
 *
 * @access  public
 * @param   string      $sn         数据的唯一值
 * @param   string      $action     操作的类型
 * @param   string      $content    操作的内容
 * @return  void
 */
function admin_log($sn = '', $action='', $content='', $name='admin_log')
{
    $action  = empty($action)  ? '' : lang($action);
    $content = empty($content) ? '' : lang($content);
    $sn      = empty($sn) ? '' : ': '.addslashes($sn);
    
    $log_info = $action.$content.$sn;

    $data = array(
        'log_info'   => $log_info,
        'log_time'   => time(),
        'user_id'    => cmf_get_current_admin_id(),
        'ip_address' => get_client_ip(0,true),
        'site_id'    => get_site_id(),
    );
    
    $insertID = Db::name($name)->insert($data);

    return $insertID;
}


/**
 * 操作权限检查，用于判断是否隐藏对应按钮
 */
function actions_check($action, $actions)
{
    $adminId = cmf_get_current_admin_id();
    if( !empty($actions) ){
        foreach ($actions as $k => $v) {
            if( !cmf_auth_check($adminId, $action.$v) ){
                unset($actions[$k]);
            }
        }
    }

    return $actions;
}
